import { parseColorText } from '../../../common/color/color';

const layouts = {
	panel: {
		x: 0, ySrc: 1120, yDst: 838, width: 1920, height: 242,
		leftBg : { x:    0, y: 0, width: 790, height: 242 }, // 相对于 panel
		rightBg: { x: 1130, y: 0, width: 790, height: 242 }, // 相对于 panel
	},
	pickSeats: {
		// 这里的都是相对 panel (左上角, 不含计时条) 的位置
		PL1: {
			x:    0, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX: 157, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PL2: {
			x:  158, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX: 157, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PL3: {
			x:  316, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX: 157, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PL4: {
			x:  474, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX: 157, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PL5: {
			x:  632, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX: 157, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PR1: {
			x: 1130, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX:   0, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PR2: {
			x: 1288, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX:   0, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PR3: {
			x: 1446, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX:   0, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PR4: {
			x: 1604, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX:   0, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
		PR5: {
			x: 1762, ySrc: 242, yDst: 0, width: 158, height: 242,
			splitX:   0, splitY1: 14, splitY2: 230, splitWidth: 1,
			nameX: 9, nameY: 230, nameWidth: 140,
		},
	},
	timeBar: {
		// 这里的都是相对 panel (左上角, 不含计时条) 的位置
		x: 0, y: -10, width: 1920, height: 10,
	},
	avatar: {
		// 这里的都是相对 panel (左上角, 不含计时条) 的位置
		x: 790, y: 0, width: 340, height: 242,
		icon: { // 相对 avatar (左上角) 的位置
			x: 110, y: 10, width: 118, height: 111,
		},
		txPatch: { // 相对 avatar (左上角) 的位置
			x: 170, ySrc: 161, yDst: 450,
		},
		teamLeft: { // 相对 avatar (左上角) 的位置, 字体右对齐
			xSrc: -70, xDst: 130, y: 174
		},
		teamRight: { // 相对 avatar (左上角) 的位置, 字体左对齐
			xSrc: 405, xDst: 205, y: 174
		},
		scoreLeft: { // 相对 avatar (左上角) 的位置, 字体右对齐
			xSrc: -70, xDst: 130, y: 201
		},
		scoreRight: { // 相对 avatar (左上角) 的位置, 字体左对齐
			xSrc: 405, xDst: 205, y: 201
		},
		arrowLeft: { // 相对 avatar (左上角) 的位置, 字体右对齐
			xSrc: -40, xDst: 160, y: 128, width: 21, height: 30,
		},
		arrowRight: { // 相对 avatar (左上角) 的位置, 字体左对齐
			xSrc: 360, xDst: 160, y: 128, width: 21, height: 30,
		},
	},
	banner: { // 相对于 panel
		left : {
			xSrc: -900, xDst:    0, y: 0, width: 790, height: 242,
			splitX: 510, splitY: 90, splitWidth: 1, splitHeight: 60,
			titleX: 366, titleY: 170, scoreX: 550, scoreY: 120,
			subX: 550, subY: 152, subWidth: 210,
			iconX: 135, iconY: 121,
		},
		right: {
			xSrc: 2030, xDst: 1130, y: 0, width: 790, height: 242,
			splitX: 279, splitY: 90, splitWidth: 1, splitHeight: 60,
			titleX: 423, titleY: 170, scoreX: 240, scoreY: 120,
			subX: 240, subY: 152, subWidth: 210,
			iconX: 655, iconY: 121,
		},
	},

	banBars: {
		left : { xSrc:-474, xDst:   0, y: 738, width: 474, height: 90 },
		right: { xSrc:1920, xDst:1446, y: 738, width: 474, height: 90 },
	},
	banSeats: {
		// 这里的都是相对 banBars (左上角) 的位置
		BL1: { x:   0, y: 0, width: 90, height: 90, splitX: 89, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BL2: { x:  90, y: 0, width: 90, height: 90, splitX: 89, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BL3: { x: 180, y: 0, width: 90, height: 90, splitX: 89, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BL4: { x: 294, y: 0, width: 90, height: 90, splitX: 89, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BL5: { x: 384, y: 0, width: 90, height: 90, splitX: 89, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BR1: { x: 384, y: 0, width: 90, height: 90, splitX:  0, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BR2: { x: 294, y: 0, width: 90, height: 90, splitX:  0, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BR3: { x: 204, y: 0, width: 90, height: 90, splitX:  0, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BR4: { x:  90, y: 0, width: 90, height: 90, splitX:  0, splitY1: 10, splitY2: 80, splitWidth: 1 },
		BR5: { x:   0, y: 0, width: 90, height: 90, splitX:  0, splitY1: 10, splitY2: 80, splitWidth: 1 },
	},
	banSeat: {
		slash: {
			x1: 24, x2: 66, y1: 24, y2: 66, width: 3
		}
	}
};

const color = {
	left: '#022deb',
	right: '#050505',
	white: '#FFFFFF',
	leftTransparent: '#022deb00',
	rightTransparent: '#05050500',
	title: '#050505',
	sub: '#484848',
	panel: {
		bg : '#e0e0e0'
	},
	pickSeats: {
		bg1: '#c0c0c0', bg2: '#e0e0e0', split: '#181818'
	},
	timeBar: {
		light: '#022deb', bg: '#484848', line: '#c0d0e0'
	},
	banBars: {
		bg : '#e0e0e0'
	},
	banSeats: {
		split: '#181818',
		slashLeft: '#022deb',
		slashRight: '#050505',
		slashLight: '#FFFFFF'
	}
};

const assets = {
	's11_icon' : 'assets/s11_icon.png', 
	iconPathFunc : (team) => `assets/${team}_icon.png`,
	banPathFunc : (hero) => `assets/ban/${hero}.png`, // 比如 image = 'lol/Aatrox.png'
	pickPathFunc : (hero) => `assets/pick/${hero}.jpg`,
	pickManifest : 'assets/pick/manifest/lol_s11.json',
};

const paths = {
	top : {
		light: 'M20,58c0,0,7 -6.7,7 -7s0 -19,0 -19s19.2,0,19.5,0s7.5 -7,7.5 -7H20V58z',
		dark: 'M34,39c0.1 -0.1,9.9 -0.1,10,0s0.1,9.9,0,10s-9.9,0.1 -10,0S33.9,39.1,34,39z'
			+ 'M24,63h34V29c0,0 -7,6.8 -7,7s0,20,0,20s-19.8,0 -20,0S24,63,24,63z',
	},
	jug : {
		light: 'M20,36c5,4,6,13,6,17c4,3,9,7,13,12c5 -14 -1.5 -28.5 -12 -42'
			+ 'c3.1,6.8,6.6,15,6,24C29.5,41,24.1,36.3,20,36z'
			+ 'M41,39c1.2,2.4,2.2,5.1,3,8c1 -9,4 -17.4,7.7 -25.3C47,27.4,43.8,33.1,41,39z'
			+ 'M45,60c0.6 -11.2,5 -19.4,13 -25c-3.6,5.5 -6.1,11.4 -6,18C49.7,54.8,47.3,57.2,45,60z'
	},
	mid : {
		light: 'M20,58c0,0.6,0,5,0,5s4.5,0,5,0s33 -32.6,33 -33s0 -5,0 -5s-4.5,0 -5,0S20,57.4,20,58z',
		dark: 'M27,32c0.1 -0.1,23.9 -0.1,24,0c0.1,0.1,0.1,22.9,0,23s-23.9,0.1 -24,0S26.9,32.1,27,32z'
			+ 'M58,63c0,0,0 -33.7,0 -34.4c0 -0.7 -2.7 -3.6 -3.7 -3.6'
			+ 'S20,25,20,25s0,33.4,0,34.2s3.5,3.8,4.6,3.8S58,63,58,63z',
	},
	bot : {
		light: 'M24,63h34V29c0,0 -7,6.8 -7,7s0,20,0,20s-19.8,0 -20,0S24,63,24,63z',
		dark: 'M20,58c0,0,7 -6.7,7 -7s0 -19,0 -19s19.2,0,19.5,0s7.5 -7,7.5 -7H20V58z'
			+ 'M34,39c0.1 -0.1,9.9 -0.1,10,0s0.1,9.9,0,10s-9.9,0.1 -10,0S33.9,39.1,34,39z',
	},
	sup : {
		light: 'M39,33.3c-0.8,0 -8 -10 -8 -10s1 -3,2 -3s11,0,12,0s2,3,2,3S39.8,33.3,39,33.3z'
			+ 'M38,37.3c1,0,1.1,0,2,0c0.9,0,5,23,5,23l-6,5l-6 -5C33,60.3,37,37.3,38,37.3z'
			+ 'M44,35.3l5 -5h17l-7,6l-7,1v1l3,5l-7,3l-4 -9V35.3z'
			+ 'M34,35.3l-5 -5H12l7,6l7,1v1l -3,5l7,3l4 -9V35.3z'
	},
};

function createMask(colorText) {
	const width = 158, height = 242;

	// 158 x 242
	const canvas = document.createElement('canvas');
	canvas.width = width;
	canvas.height = height;
	const ctx2d = canvas.getContext("2d"); // CanvasRenderingContext2D

	const color = parseColorText(colorText);
	if (color == null) {
		throw 'invalid color string: ' + colorText;
	}
	const colorArray = [ color ];
	for (let i = 0; i < 17; i ++) {
		const c = color.clone();
		c.a = 255 - 15 * i;
		colorArray[i] = c;
	}

	const imageData = ctx2d.getImageData(0, 0, width, height);
	const data = imageData.data;
	for (let x = 0; x < width; x++) {
		for (let y = 0; y < height; y++) {
			let distance = Math.min(x, y, width - x, height - y);
			let c = colorArray[distance];
			if (!c) {
				continue;
			}
			const index = (y * width + x) * 4;
			data[index] = c.r;
			data[index + 1] = c.g;
			data[index + 2] = c.b;
			data[index + 3] = c.a;
		}
	}
	ctx2d.putImageData(imageData, 0, 0);
	return canvas;
}

function fetchPickManifest(context) {
	return fetch(context.assetPath(assets.pickManifest))
			.then(d => d.json());
}

const imageCache = {};
const blurMapper = {
	offsetX : 3, offsetY : 3,
	matrix : [
		[ 0, 0, 0, 1, 0, 0, 0 ],
		[ 0, 0, 1, 1, 1, 0, 0 ],
		[ 0, 1, 1, 1, 1, 1, 0 ],
		[ 1, 1, 1, 2, 1, 1, 1 ],
		[ 0, 1, 1, 1, 1, 1, 0 ],
		[ 0, 0, 1, 1, 1, 0, 0 ],
		[ 0, 0, 0, 1, 0, 0, 0 ],
	],
	sum : 26,
}

function createPickImages(manifest, hero, path) {
	const width = 158, height = 242;
	if (imageCache[hero]) {
		const canvas = document.createElement('canvas');
		canvas.width = width;
		canvas.height = height;
		const ctx2d = canvas.getContext("2d");
		ctx2d.putImageData(imageCache[hero], 0, 0);
		return Promise.resolve(canvas);
	}

	const image = document.createElement('img');
	let v = manifest[hero];

	return new Promise((resolve, reject) => {
		image.onload = () => {
			resolve();
		};
		image.onerror = (e) => {
			reject(e);
		};
		image.src = path;
	}).then(_ => {
		const canvas = document.createElement('canvas');
		canvas.width = width;
		canvas.height = height;
		const ctx2d = canvas.getContext("2d");

		if (v == null) {
			let w = image.height * 158 / 242;
			v = { w, h: image.height, x: (image.width - w) / 2, y: 0 };
		}
		if (v.flipX) {
			ctx2d.translate(width, 0);
			ctx2d.scale(-1, 1);
		}
		ctx2d.drawImage(image, v.x, v.y, v.w, v.h, 0, 0, width, height);
		ctx2d.resetTransform();

		// blur: y >= 150
		const imageData = ctx2d.getImageData(0, 0, width, height);
		const oldData = imageData.data;
		const newData = new Uint8ClampedArray(oldData);
		const toIndex = (x, y) => {
			x = x < 0 ? 0 : x >= width ? width - 1 : x;
			y = y < 0 ? 0 : y >= height ? height - 1 : y;
			return (y * width + x) * 4;
		};
		const blur = (x, y) => {
			const baseIndex = toIndex(x, y);
			const offx = blurMapper.offsetX, offy = blurMapper.offsetY;
			const matrix = blurMapper.matrix;
			for (let i = 0; i < 3; i++) { // GRBA 的 A 不用管
				let sum = 0;
				for (let dy = 0; dy < matrix.length; dy++) {
					let array = matrix[dy];
					for (let dx = 0; dx < array.length; dx++) {
						let weight = array[dx];
						if (weight == 0) {
							continue;
						}
						sum += oldData[toIndex(x-offx+dx, y-offy+dy) + i] * weight;
					}
				}
				newData[baseIndex + i] = sum / blurMapper.sum;
			}
		}

		for (let x = 0; x < width; x++) {
			for (let y = 150; y < height; y++) {
				blur(x, y);
			}
		}
		const cache = new ImageData(width, height);
		cache.data.set(newData);
		imageCache[hero] = cache;

		oldData.set(newData);
		ctx2d.putImageData(imageData, 0, 0);
		return canvas;
	});
}

export {
	layouts, color, assets, paths,
	createMask, fetchPickManifest, createPickImages,
};